package org.vectrics.common.graphics;

import javax.servlet.*;
import javax.servlet.http.*;

import java.io.ByteArrayOutputStream;
import java.io.*;
import java.util.*;
import org.apache.log4j.Category;
import javax.naming.InitialContext;
import org.vectrics.VectricsException;
import java.awt.image.BufferedImage;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;



public class GraphicsGenServlet extends HttpServlet {
    private static final String CONTENT_TYPE = "text/html";
    private static Category log = Category.getInstance(GraphicsGenServlet.class);
    private boolean initialized = false;

    
    /**Initialize global variables*/
    public void init() throws ServletException {
    	super.init();
        log.debug("RecruiterServlet initializing.");
        initialized = true;
    }

    /**Process the HTTP Get request*/
    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	log.debug("service() - handling request for PDF report");
    	if (initialized == false) {
    		init();
    	}

		String awtToolKit = System.getProperty("awt.toolkit");
		String awtGraphicEnv = System.getProperty("java.awt.graphicsenv");
		String awtFont = System.getProperty("java.awt.fonts");
		log.info("GRAPHICS: awt.toolkit = " + awtToolKit);
		log.info("GRAPHICS: java.awt.graphicsenv = " + awtGraphicEnv);
		log.info("GRAPHICS: java.awt.fonts = " + awtFont);


    	
		byte[] reportBytes;
		try {
			InitialContext context = new InitialContext();
			Enumeration envElements = context.getEnvironment().elements();
			while (envElements.hasMoreElements()) {
				envElements.nextElement();
			}
		}
		catch (Exception ex) {
			log.error("Exception getting initial context",ex);
		}
		
		
		String reportParam = request.getParameter("report");
		log.debug("Report param = " + reportParam);
		try {
			Date now = new Date();
			long time = now.getTime();
			ByteArrayOutputStream outStream = new ByteArrayOutputStream();

					
			makeGraphic(request, outStream);				

			if (log.isDebugEnabled()) {
				log.debug("Output stream length = " + outStream.size());
				log.debug("Converting output stream to byte array");
			}
			reportBytes = outStream.toByteArray();
			
		}
		catch (VectricsException ve) {
			throw new ServletException("VectricsException building graphic", ve);
		}
		catch (Exception ex) {
			throw new ServletException("Exception building report", ex);
		}

		
		Date now = new Date();
		long time = now.getTime();
		
		log.debug("Setting content type");
		response.setContentType("application/pdf");
		
		log.debug("Writing bytes to response");
		log.debug("Size of byte array = " + reportBytes.length);
		response.getOutputStream().write(reportBytes);
		response.setContentLength(reportBytes.length);
		
		log.info("Flushing response");
		response.getOutputStream().flush();
		
    }

	void makeGraphic(HttpServletRequest request, OutputStream out) throws VectricsException {
		
		float quality = 0.9f;
		
		Graphic graphic = null;
		String type = request.getParameter("type").toLowerCase();
		if (type == null) {
			log.error("parameter 'type' not specified in request for graphic");
			throw new VectricsException("parameter 'type' not specified in request for graphic");
		} 
		if (type.equals("logo")) {
			graphic = new LogoGraphic(request);
		}
		else if (type.equals("text")) {
			graphic = new TextGraphic(request);	
		}

		if (graphic == null) {
			log.error("Could not find the graphic definition for 'type' = " + type);
			throw new VectricsException("Could not find the graphic definition for 'type' = " + type);
		}		

		BufferedImage chartImage = createBufferedImage(graphic);
		try {
			writeBufferedImageAsJPEG(out, quality, chartImage);
		}
		catch (Exception ex) {
			log.error("Exception occurred while converting image to jpeg", ex);
		}

	}

	
	public BufferedImage createBufferedImage(Graphic graphic) {
		BufferedImage image = graphic.fill();
		return image;
	}
	
	public static void writeBufferedImageAsJPEG(OutputStream out, float quality,
												BufferedImage image) throws IOException {
		JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
		JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(image);
		param.setQuality(quality, true);
		encoder.encode(image, param);

	}

}